package com.whc.gulimall.ware.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whc.common.to.mq.StockDetailTo;
import com.whc.common.to.mq.StockLockedTO;
import com.whc.common.utils.PageUtils;
import com.whc.common.utils.Query;
import com.whc.gulimall.ware.constant.WareMQConstant;
import com.whc.gulimall.ware.dao.WareInfoDao;
import com.whc.gulimall.ware.entity.WareInfoEntity;
import com.whc.gulimall.ware.entity.WareOrderTaskDetailEntity;
import com.whc.gulimall.ware.entity.WareOrderTaskEntity;
import com.whc.gulimall.ware.exception.NoStockException;
import com.whc.gulimall.ware.service.WareInfoService;
import com.whc.gulimall.ware.service.WareOrderTaskDetailService;
import com.whc.gulimall.ware.service.WareOrderTaskService;
import com.whc.gulimall.ware.vo.ProductLockVo;
import com.whc.gulimall.ware.vo.WareLockVo;
import com.whc.gulimall.ware.vo.WareStockMapVo;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * @author angaoen
 */
@Service("wareInfoService")
public class WareInfoServiceImpl extends ServiceImpl<WareInfoDao, WareInfoEntity> implements WareInfoService {

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private WareOrderTaskService wareOrderTaskService;

    @Resource
    private WareOrderTaskDetailService wareOrderTaskDetailService;

    /**
     * 查询分页数据
     *
     * @param params 查询条件以及分页条件
     * @return 分页数据
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<WareInfoEntity> queryWrapper = new QueryWrapper<>();
        String key = (String) params.get("key");
        if (StrUtil.isNotEmpty(key)) {
            queryWrapper.eq("id", key)
                    .or().like("name", key)
                    .or().like("address", key)
                    .or().like("areacode", key);
        }
        IPage<WareInfoEntity> page = this.page(new Query<WareInfoEntity>().getPage(params), queryWrapper);
        return new PageUtils(page);
    }

    /**
     * 获取到地址运费
     *
     * @param addrId 地址Id
     * @return 地址信息
     */
    @Override
    public BigDecimal getAddressFareByAddrId(Long addrId) {
        return new BigDecimal(RandomUtil.randomInt(0, 10) + "");
    }

    /**
     * 锁库存
     *
     * @param lockVo 订单信息vo
     * @return 结果列表
     */
    @Override
    @Transactional(rollbackFor = NoStockException.class)
    public Boolean orderLockedStock(WareLockVo lockVo) {
        // 记录库存工作单的详情
        WareOrderTaskEntity taskEntity = new WareOrderTaskEntity();
        taskEntity.setOrderSn(lockVo.getOrderSn());
        wareOrderTaskService.save(taskEntity);

        List<ProductLockVo> productVoList = lockVo.getProductVos();
        // 通过skuId在库存表中查询,在哪个仓库有足够的库存
        List<WareStockMapVo> mapVos = baseMapper
                .listHasStockWareBySkuIds(productVoList.stream().map(ProductLockVo::getSkuId).collect(Collectors.toList()));
        if (CollUtil.isNotEmpty(mapVos)) {
            Map<Long, String> wareMap = mapVos
                    .stream().collect(Collectors.toMap(WareStockMapVo::getSkuId, WareStockMapVo::getWareIdStr));
            if (CollUtil.isNotEmpty(wareMap)) {
                // 锁定订单
                for (ProductLockVo productVo : productVoList) {
                    // 当前商品锁定状态
                    boolean skuStockStatus = false;
                    Long skuId = productVo.getSkuId();
                    String wareIdStr = wareMap.get(skuId);
                    if (StrUtil.isNotBlank(wareIdStr)) {
                        for (Long wareId : ArrayUtil.wrap(StrUtil.splitToLong(wareIdStr, ','))) {
                            Integer result = baseMapper.lockSkuStock(skuId, productVo.getCount(), wareId);
                            if (Objects.equals(1, result)) {
                                // 锁定成功
                                skuStockStatus = true;
                                // 订单详情表记录
                                WareOrderTaskDetailEntity detailEntity = new WareOrderTaskDetailEntity(null, skuId,
                                        "", productVo.getCount(), taskEntity.getId(), wareId, 1);
                                wareOrderTaskDetailService.save(detailEntity);
                                // 通知mq锁定成功
                                StockLockedTO stockLockedTO = new StockLockedTO();
                                stockLockedTO.setId(taskEntity.getId());
                                StockDetailTo stockDetailTo = new StockDetailTo();
                                BeanUtil.copyProperties(detailEntity, stockDetailTo);
                                stockLockedTO.setStockDetailTo(stockDetailTo);
                                rabbitTemplate.convertAndSend(WareMQConstant.STOCK_EVENT_EXCHANGE,
                                        "stock.locked", stockLockedTO);
                                break;
                            } else {
                                // 锁定失败
                            }
                        }
                    } else {
                        throw new NoStockException(skuId);
                    }
                    if (!skuStockStatus) {
                        throw new NoStockException(skuId);
                    }
                }
                return true;
            }
        }

        return false;
    }

}
